package com.quartet.modules.stock.service.impl;

import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quartet.api.MapServerException;
import com.quartet.api.ResultErrorEnum;
import com.quartet.modules.service.entity.TServiceInfo;
import com.quartet.modules.service.service.TServiceInfoService;
import com.quartet.modules.stock.dao.TTerminalStockDao;
import com.quartet.modules.stock.dto.TTerminalServiceMessageDto;
import com.quartet.modules.stock.entity.TTerminalStock;
import com.quartet.modules.stock.service.TTerminalStockService;
import com.quartet.modules.system.service.DictDetailServicePs;
import com.quartet.utils.JsonTool;
import com.quartet.utils.StringUtils;
import com.quartet.utils.constant.MapServerConstant;
import com.quartet.utils.enums.InventoryStatusEnum;
import com.quartet.utils.enums.ServiceStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 终端库存表(TTerminalStock)表服务实现类
 *
 * @author makejava
 * @since 2021-06-20 09:07:34
 */
@Service("tTerminalStockService")
@Slf4j
public class TTerminalStockServiceImpl extends ServiceImpl<TTerminalStockDao, TTerminalStock> implements TTerminalStockService {

    @Autowired
    private TServiceInfoService tServiceInfoService;

    @Autowired
    private DictDetailServicePs dictDetailServicePs;


    /**
     * 批量导入终端库存信息
     *
     * @param file
     */
    @Override
    public void batchImportTerminalStock(MultipartFile file) throws IOException {
        //获取Excel文件名称
        String originalFilename = file.getOriginalFilename();
        //获取文件扩展名
        String substring = originalFilename.substring(originalFilename.indexOf(".") + 1);
        List<TTerminalStock> tTerminalStockList = null;
        //如果是xls文件进入
        if (substring.equals("xls")) {
            InputStream inputStream = file.getInputStream();
            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
            HSSFSheet sheetAt = workbook.getSheetAt(0);
            tTerminalStockList = getTerminalStockList(sheetAt);

        }

        //如果是xlsx文件进入
        if (substring.equals("xlsx")) {
            InputStream inputStream = file.getInputStream();
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            XSSFSheet sheetAt = workbook.getSheetAt(0);
            tTerminalStockList = getTerminalStockList(sheetAt);
        }
        this.saveBatch(tTerminalStockList);
    }

    /**
     * 批量导出终端库存信息
     *
     * @param response
     * @param idList
     */
    @Override
    public void batchExportTerminalStock(HttpServletResponse response, List<Integer> idList) throws IOException {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        QueryWrapper<TTerminalStock> queryWrapper = new QueryWrapper<>();
        if (!CollectionUtils.isEmpty(idList)) {
            queryWrapper.lambda().in(TTerminalStock::getId, idList);
        }
        List<TTerminalStock> tTerminalStockList = this.baseMapper.selectList(queryWrapper);
        //将javaBean转到excel中
        //創建一個workbook
        Workbook wrkbook = new XSSFWorkbook();
        //在workbook中創建一個Sheet
        Sheet sheet = wrkbook.createSheet();
        //添加表頭行
        Row row = sheet.createRow(0);
        //創建單元格
        Cell cell = row.createCell(0);
        cell.setCellValue("终端编码");
        cell = row.createCell(1);
        cell.setCellValue("设备型号");
        cell = row.createCell(2);
        cell.setCellValue("协议");
        cell = row.createCell(3);
        cell.setCellValue("入库时间");
        cell = row.createCell(4);
        cell.setCellValue("出库时间");
        cell = row.createCell(5);
        cell.setCellValue("库存状态");
        //寫入實體數據
        int s = 1;
        for (TTerminalStock tTerminalStock : tTerminalStockList) {
            row = sheet.createRow(s);
            row.createCell(0).setCellValue(tTerminalStock.getTerminalCode());
            row.createCell(1).setCellValue(tTerminalStock.getTerminalModel());
            String protocol = tTerminalStock.getProtocol();
            if (StringUtils.isNotBlank(protocol)) {
                String protocolLabel = dictDetailServicePs.getLabelByValueByCodeAndName(protocol, MapServerConstant.PROTOCOL_TYPE);
                row.createCell(2).setCellValue(protocolLabel);
            } else {
                row.createCell(2).setCellValue("");
            }
            row.createCell(3).setCellValue(df.format(tTerminalStock.getStorageTime()));
            row.createCell(4).setCellValue(tTerminalStock.getDeliveryTime() == null ? "" : df.format(tTerminalStock.getDeliveryTime()));
            row.createCell(5).setCellValue(InventoryStatusEnum.find(tTerminalStock.getInventoryStatus()).getDescription());
            s++;
        }
        //輸出excel文件
        OutputStream os = response.getOutputStream();
        BufferedOutputStream bs = new BufferedOutputStream(os);
        //清除空白行
        response.reset();
        response.setHeader("Content-disposition", "attachment;filename=" + new Date().getTime() + ".xlsx");
        response.setContentType("application/msexcel");
        wrkbook.write(bs);
        os.close();
    }

    /**
     * 发送设备服务权限信息
     */
    @Override
    public void sendTTerminalServiceMessageDto() {
        List<TTerminalServiceMessageDto> tTerminalServiceMessageDtoList = this.baseMapper.queryTerminalOrder(null);
        log.info("queryTerminalOrder result is {}", tTerminalServiceMessageDtoList);

        List<String> orderCodeList = tTerminalServiceMessageDtoList.stream().map(TTerminalServiceMessageDto::getOrderCode).filter(x -> !Objects.isNull(x)).distinct().collect(Collectors.toList());

        List<TServiceInfo> tServiceInfoList = tServiceInfoService.list(new QueryWrapper<TServiceInfo>().lambda()
                .in(TServiceInfo::getOrderCode, orderCodeList)
                .eq(TServiceInfo::getStatus, ServiceStatusEnum.ENABLE.getValue())
                .in(TServiceInfo::getServiceType, MapServerConstant.SERVICE_TYPE_LIST));
        Map<String, List<String>> map = tServiceInfoList.stream().collect(Collectors.groupingBy(TServiceInfo::getOrderCode, Collectors.mapping(TServiceInfo::getServiceType, Collectors.toList())));

        tTerminalServiceMessageDtoList.forEach(tTerminalServiceMessageDto -> {
            List<String> serviceTypeList = map.get(tTerminalServiceMessageDto.getOrderCode());
            if (!CollectionUtils.isEmpty(serviceTypeList)) {
                tTerminalServiceMessageDto.setLocationAuth(serviceTypeList.contains(MapServerConstant.LOCATION));
                tTerminalServiceMessageDto.setAlarmAuth(serviceTypeList.contains(MapServerConstant.ALARM));
            }
        });
        //发送给协议解析方
        String json = JsonTool.beanToJson(tTerminalServiceMessageDtoList);
        String result = HttpUtil.post(MapServerConstant.AUTHORITY, json);
        if (!"success".equals(result)) {
            throw new MapServerException(ResultErrorEnum.BMKPF003);
        }
        log.info("调用http://8.141.63.229:97/terminal/authority，参数为：{}，返回信息：{}", json, result);
    }

    /**
     * 解析sheet成javaBean
     *
     * @param sheet
     * @return
     */
    private List<TTerminalStock> getTerminalStockList(Sheet sheet) {
        List<TTerminalStock> tTerminalStockList = new ArrayList<>();
        List<String> terminalCodeList = new ArrayList<>();
        //第一行是列名所以不读 获取第一行的下标 下标从0开始
        int firstRowIndex = sheet.getFirstRowNum() + 1;
        //获取最后一行的下标
        int lastRowIndex = sheet.getLastRowNum();
        //循环每一行
        for (int rIndex = firstRowIndex; rIndex <= lastRowIndex; rIndex++) {
            //获取某一行的数据
            Row row = sheet.getRow(rIndex);
            //如果该行不等于空
            if (row != null) {
                //获取某一行的第一个单元格的下标  下标从1开始
                int firstCellIndex = row.getFirstCellNum();
                //获取某一行的最后一个单元格的下标
                int lastCellIndex = row.getLastCellNum();
                TTerminalStock tTerminalStock = new TTerminalStock();
                for (int cIndex = firstCellIndex; cIndex < lastCellIndex; cIndex++) {
                    //获取某一格的数据
                    Cell cell = row.getCell(cIndex);
                    cell.setCellType(CellType.STRING);
                    switch (cIndex) {
                        case 0: {
                            tTerminalStock.setTerminalCode(cell.getStringCellValue());
                            break;
                        }
                        case 1: {
                            tTerminalStock.setTerminalModel(cell.getStringCellValue());
                            break;
                        }
                        case 2: {
                            tTerminalStock.setProtocol(StringUtils.isNotBlank(cell.getStringCellValue()) ? cell.getStringCellValue() : "0");
                            break;
                        }
                    }
                }
                QueryWrapper<TTerminalStock> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(TTerminalStock::getTerminalCode, tTerminalStock.getTerminalCode());
                List<TTerminalStock> list = this.baseMapper.selectList(queryWrapper);
                if (!CollectionUtils.isEmpty(list)) {
                    throw new MapServerException(ResultErrorEnum.BMKPZ005);
                }
                if (terminalCodeList.contains(tTerminalStock.getTerminalCode())) {
                    throw new MapServerException(ResultErrorEnum.BMKPZ006);
                }
                tTerminalStock.setStorageTime(LocalDateTime.now());
                tTerminalStock.setInventoryStatus(InventoryStatusEnum.UNALLOCATED.getValue());
                terminalCodeList.add(tTerminalStock.getTerminalCode());
                tTerminalStockList.add(tTerminalStock);
            }
        }
        return tTerminalStockList;
    }
}
